/* typehinst:start */
import { GameRoot } from "../../root";
import { Npc } from "../../npcs/npc";
/* typehinst:end */

import { animRemoveElement, getObjectType, makeDiv, slowOutText } from "../../../core/utils/utils";
import { BaseHUDPart } from "../base_hud_part";
import { DynamicDom } from "../dynamic_dom";
import { Signal } from "../../../core/utils/signal";

export class HUDDialogue extends BaseHUDPart{
  /** @type {GameRoot} */
  constructor(root){
    super(root);
  }

  createElements(parent){
    this.element = makeDiv(parent, 'dialogue', [], `
      <div class="screen"></div>
      <div class="wrapper">
        <div class="btns-pos">
          <div class="btn-list">
            <div></div>
            <div class="btn remove showShop"><img src="res/ui/icons/shop.svg" /> 交易</div>
            <div class="btn closeDialogue">再见！</div>
          </div>
        </div>
        <div class="message">
          <div class="title">
            <h3></h3>
          </div>
          <div class="content">
          </div>
        </div>
      </div>
    `);
  }
  
  initialize(){
    this.domAttach = new DynamicDom(this.root, this.element);

    /** @type {Npc} */
    this.npc = null;

    this.handleButton();
  }

  handleButton(){
    this.trackClicks(this.element.querySelector('.closeDialogue'), () => {
      this.handleHideDialogue();
    }, {
      applyCssClass: ''
    })
    this.trackClicks(this.element.querySelector('.showShop'), () => {
      this.root.hud.parts.shopBoard.handleShow(this.npc);
      this.handleHideDialogue();
    }, {
      applyCssClass: ''
    })
  }

  /**
   * 显示所有可以对话序列
   * @param {*} npc 
   */
  handleShowDialogue(npc){
    this.npc = npc;
    this.domAttach.internalAttach();
    this.showShopBtn(npc);
    this.showDialogueMessage(npc);
    this.element.querySelector('.closeDialogue').classList.remove('remove');
  }

  /**
   * 显示指定对话序列
   * @param {*} npc 
   */
  handleAppointDialogue(npc, key = '', showClose = false){
    assert(!(key === ''), '指定对话ID为空')
    this.npc = npc;
    this.domAttach.internalAttach();
    this.showAppointDialogueMessage(npc, key);
    this.element.querySelector('.closeDialogue').classList.toggle('remove', !showClose);
  }

  showShopBtn(npc){
    let shopShopBtn = this.element.querySelector('.showShop')
    if(npc.getIsShop()) {
      shopShopBtn.classList.remove('remove');
    } else {
      shopShopBtn.classList.add('remove');
    }
  }

  showAppointDialogueMessage(npc, key){
    let title = this.element.querySelector('.title h3');
    let content = this.element.querySelector('.content');

    npc.dialogue.clear();
    npc.dialogueDefine()(npc);
    let dialogue = npc.dialogue.find(key);

    title.innerHTML = npc.getName();
    // content.innerHTML = dialogue.dialogues[0].message;

    slowOutText(content, dialogue.dialogues[0].message)

    let endSignal = new Signal();

    this.showDialogueBtns(npc, dialogue.dialogues, 1, {
      groups: dialogue.dialogues,
      index: 0,
      end: endSignal
    });

    endSignal.add(() => {
      this.element.querySelector('.closeDialogue').classList.remove('remove');
    })
  }

  /**
   * 
   * @param {Npc} npc 
   */
  showDialogueMessage(npc){
    let title = this.element.querySelector('.title h3');
    let content = this.element.querySelector('.content');
    title.innerHTML = npc.getName();
    // content.innerHTML = npc.getMessage();
    slowOutText(content, npc.getMessage())

    // 设置所有对话
    npc.dialogue.clear();
    npc.dialogueDefine()(npc);
    this.showDialogueBtns(npc, [npc.dialogue.groups], 0);
  }

  /**
   * 显示每一步的所有可选对话
   * @param {Npc} npc 
   */
  showDialogueBtns(npc, groups, index = 0, payload = {}){
    let btnWrapper = this.element.querySelector('.btn-list > div');
    btnWrapper.innerHTML = '';

    if(!groups[index]) {
      this.showDialogueBtns(npc, payload.groups || [npc.dialogue.groups], payload.index || 0, payload);
      if(payload.end){
        payload.end.dispatch();
      }
      return;
    }

    if(getObjectType(groups[index]) === 'Array'){
      let group = npc.dialogue.showGroups(groups[index]);
      let btns = [];

      for(let i = 0; i < group.length; i++){
        let dialogueSection = group[i].dialogues[0];
        let dialogueBtn = makeDiv(btnWrapper, '', ['btn'], `${dialogueSection.me}`);

        btns.push(dialogueBtn);

        this.trackClicks(dialogueBtn, () => {
          btns.map(btn => {
            if(btn !== dialogueBtn){
              btnWrapper.removeChild(btn)
            } else { 
              btn.classList.add('active')
            }
          })

          this.internalDialogueBtnActived(npc, dialogueSection, group[i].dialogues, index, payload);
        }, {
          applyCssClass: ''
        })
      }
    } else {
      let dialogueSection = groups[index];
      let dialogueBtn = makeDiv(btnWrapper, '', ['btn'], `${dialogueSection.me}`);

      this.trackClicks(dialogueBtn, () => {
        dialogueBtn.classList.add('active')

        this.internalDialogueBtnActived(npc, dialogueSection, groups, index, payload);
      }, {
        applyCssClass: ''
      })
    }
  }

  internalDialogueBtnActived(npc, dialogueSection, nextGroup, index, payload){
    let content = this.element.querySelector('.content');
    let title = this.element.querySelector('.title h3');
    title.innerHTML = npc.getName();

    animRemoveElement(content, () => {
      // content.innerHTML = dialogueSection.message;
      slowOutText(content, dialogueSection.message)
    }, 300)

    if(dialogueSection.click){
      dialogueSection.click();
    }

    if(dialogueSection.closeDialogue){
      this.root.hud.signals.closeDialogue.add(
        dialogueSection.closeDialogue.bind(npc, dialogueSection)
      );
    }
    
    this.showDialogueBtns(npc, nextGroup, index + 1, payload);
  }

  handleHideDialogue(){
    this.root.hud.signals.closeDialogue.dispatch();
    this.root.hud.signals.closeDialogue.removeAll();
    animRemoveElement(this.element, () => {
      this.domAttach.internalDetach();
    }, 500)
  }
}